/*
 * TDownloader.cpp
 *
 *  Created on: 2012-11-5
 *      Author: minhua
 */

#include "TDownloader.h"

#include "../TContext.h"
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QUrl>
#include "utils/TConverter.h"
#include <QtDebug>
#include <QFile>
#include "TNetworkAccessManager.h"

TDownloader::TDownloader(TSessionPointer session, QObject *parent) : QObject(parent)
{
	_session = session;
	_timer = NULL;
	_downloadFilename = QString::null;
}

TDownloader::~TDownloader()
{
	if(_timer)
		delete _timer;
}

void TDownloader::download(QString path, QString filename, int msec)
{
	QHash<QString, QVariant> variables;
	download(path, variables, filename, msec);
}

void TDownloader::download(QString path, QHash<QString, QVariant> variables, QString filename, int msec)
{
	_downloadFilename = filename;

	variables.insert("version", TContext::instance()->config()->version());
	variables.insert("token", _session->getToken());

	TContext::instance()->logger()->debug("********* One Request *********");
	TContext::instance()->logger()->debug("Url: " + TContext::instance()->config()->serverUrl() + "/" + path);
	TContext::instance()->logger()->debug("Method: POST");

	//QNetworkAccessManager *manager = new QNetworkAccessManager(this);
	//connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(done(QNetworkReply *)));
	connect(TNetworkAccessManager::instance(), SIGNAL(done(QNetworkReply *)), this, SLOT(done(QNetworkReply *)));
	QUrl url(TContext::instance()->config()->serverUrl() + "/" + path);
	QNetworkRequest request;
	request.setUrl(url);
	QByteArray content;
	QHashIterator<QString, QVariant> iterator(variables);
	while(iterator.hasNext())
	{
		if(iterator.hasPrevious())
		{
			content.append("&");
		}
		QString key = iterator.next().key();
		content.append(key);
		content.append("=");

		QVariant value = variables.value(key);
		switch(value.type())
		{
		case QVariant::Int:
			content.append(QString::number(value.toInt()));
			break;
		case QVariant::Double:
			content.append(QString::number(value.toDouble()));
			break;
		case QVariant::String:
			content.append(value.toString().toUtf8());
			break;
		case QVariant::Date:
			content.append(TConverter::dateToString(value.toDate()));
			break;
		case QVariant::Time:
			content.append(TConverter::timeToString(value.toTime()));
			break;
		case QVariant::DateTime:
			content.append(TConverter::datetimeToString(value.toDateTime()));
			break;
		case QVariant::Bool:
			content.append(TConverter::boolToString(value.toBool()));
			break;
		default:
			break;
		}
	}
	content.replace('%', "%25");
	content.replace('+', "%2b");
	TContext::instance()->logger()->debug("Content: " + content);
	request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
	request.setHeader(QNetworkRequest::ContentLengthHeader, content.length());

	if (_timer != NULL)
		delete _timer;

	_path = TContext::instance()->config()->serverUrl() + "/" + path;
	_content = content;

	_timer = new QTimer();
	_timer->start(msec);

	connect(_timer, SIGNAL(timeout()), this, SLOT(timeout()));

	_reply = TNetworkAccessManager::instance()->post(request, content);
	connect(_reply, SIGNAL(downloadProgress(qint64, qint64)), this, SIGNAL(downloadProgress(qint64, qint64)));
	connect(_reply, SIGNAL(uploadProgress(qint64, qint64)), this, SIGNAL(uploadProgress(qint64, qint64)));

	//manager->post(request, content);
}

void TDownloader::done(QNetworkReply *reply)
{
	if (_reply != reply)
		return;

	if (_timer)
	{
		_timer->stop();
		delete _timer;
		_timer = NULL;
	}
	TContext::instance()->logger()->debug("********* One Request Done *********");
	TContext::instance()->logger()->debug("Error: " + QString::number((int)(reply->error())));

	QDomElement response;
	bool error = true;

	if(reply->error()==QNetworkReply::NoError)
	{
		QByteArray responseBody = reply->readAll();

		TContext::instance()->logger()->debug("Response Body: " + QString::fromUtf8(responseBody));

		QFile file(_downloadFilename);
		if(file.open(QFile::WriteOnly | QFile::Truncate))
		{
			file.write(responseBody);
			file.close();
			error = false;
		}
		else
		{
			TContext::instance()->logger()->error("Parse the downloader open file failed: " + _downloadFilename);
			error = true;
		}
	}

	emit finished(error);
}

void TDownloader::timeout()
{
	QTimer *tmpTimer = (QTimer*)sender();
	tmpTimer->stop();
	tmpTimer->deleteLater();
	if (tmpTimer != _timer)
	{
		return;
	}
	_timer = NULL;
	TContext::instance()->logger()->debug(_path + "?" + _content + "  timeout");
	emit finished(true);
}

QString TDownloader::getDownloadFilename()
{
	return _downloadFilename;
}
